# utils/wechat_sdk.py
import requests
import xmltodict
import hashlib
import random
import string
from typing import Dict

# 配置参数
WX_APPID = "wx48ef145fa1f16f92"
WX_MCHID = "1697745872"
WX_API_KEY = "4G7hP3K9n2F8j5D1m3L6t7R4zB0W5Yc1"
WX_NOTIFY_URL = "http://127.0.0.1:8000/pay/wechat_notify"

# ---------- 工具方法 ----------
def gen_nonce_str(length=32) -> str:
    return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length))

def sign(params: Dict[str, str], key: str) -> str:
    """生成签名"""
    stringA = "&".join([f"{k}={params[k]}" for k in sorted(params) if params[k]])
    stringSignTemp = f"{stringA}&key={key}"
    return hashlib.md5(stringSignTemp.encode("utf-8")).hexdigest().upper()

def dict_to_xml(params: Dict[str, str]) -> str:
    xml = ["<xml>"]
    for k, v in params.items():
        xml.append(f"<{k}><![CDATA[{v}]]></{k}>")
    xml.append("</xml>")
    return "".join(xml)

def xml_to_dict(xml_str: str) -> Dict:
    return xmltodict.parse(xml_str)["xml"]

# ---------- SDK 方法 ----------
def wechat_native_pay(out_trade_no: str, total_fee: float, body="VIP 开通") -> str:
    """
    微信 Native 下单，返回二维码链接
    """
    # print("微信 Native 下单，返回二维码链接")
    url = "https://api.mch.weixin.qq.com/pay/unifiedorder"
    params = {
        "appid": WX_APPID,
        "mch_id": WX_MCHID,
        "nonce_str": gen_nonce_str(),
        "body": body,
        "out_trade_no": out_trade_no,
        "total_fee": str(int(total_fee * 100)),  # 单位: 分
        "spbill_create_ip": "127.0.0.1",
        "notify_url": WX_NOTIFY_URL,
        "trade_type": "NATIVE",
    }
    params["sign"] = sign(params, WX_API_KEY)
    xml = dict_to_xml(params)

    resp = requests.post(url, data=xml.encode("utf-8"))
    result = xml_to_dict(resp.text)

    if result.get("return_code") == "SUCCESS" and result.get("result_code") == "SUCCESS":
        return result["code_url"]
    else:
        raise Exception(f"WeChat Pay error: {result}")

def wechat_order_query(out_trade_no: str) -> Dict:
    """
    微信订单查询，返回 trade_state
    """
    # print("微信订单查询，返回 trade_state")
    url = "https://api.mch.weixin.qq.com/pay/orderquery"
    params = {
        "appid": WX_APPID,
        "mch_id": WX_MCHID,
        "out_trade_no": out_trade_no,
        "nonce_str": gen_nonce_str(),
    }
    params["sign"] = sign(params, WX_API_KEY)
    xml = dict_to_xml(params)

    resp = requests.post(url, data=xml.encode("utf-8"))
    result = xml_to_dict(resp.text)
    return result
